package org.ftc.report;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;

import org.apache.commons.lang3.StringUtils;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.model.fields.merge.DataFieldName;
import org.docx4j.model.fields.merge.MailMerger;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.wml.Br;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Tc;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;
import org.ftc.domain.Committee;

public class Report3 {

	public static void main(String[] args) throws Exception {
//		String str = "(一)一二(二)三三  (三)照三";
//		String[] strs= StringUtils.split(str,"(%s)");
//		Pattern p = Pattern.compile("\\(.*?\\)");
//		Matcher m = p.matcher(str);
//		if (m.matches()) {
//		  System.out.println(m.group(1)+"    "+m.groupCount());
//		}
		report3();
	}

	
	
	private static void report3() throws Exception	{
		File tmp = new File("D:\\ftc\\1165\\目次表4_2.docx");
		WordprocessingMLPackage template = WordprocessingMLPackage.load(tmp);
		// 變數
		
		Map<DataFieldName,String> map = new HashMap<>();
		map.put(new DataFieldName("sessionNo"), "九九九九");
		map.put(new DataFieldName("date"), "103/1/1");
		
		
//		replaceTable("COLUMN1", map2, template);
		System.out.println("===================================");
		Part p  = template.getMainDocumentPart();
		List<Object> list = getAllElementFromObject(p, DataFieldName.class);
		System.out.println("list size:"+list.size());
		List<Object> tables = getAllElementFromObject(p, Tbl.class);
		Tbl tempTable = getTemplateTable(tables,"n1");
		Map<String,String> map2 = new HashMap<>();
		map2.put("n1", "1");
		map2.put("cause", "測試用的案由102年1月32日ABCDEFG。");
		map2.put("committees", "一主任委員二三一委員二三一委員二三");
		map2.put("unit1", "測試單位");
		map2.put("charge1", "測試承辦");
		map2.put("chief1", "科長一");
		map2.put("sep", "-----");
		map2.put("unit2", "測試單位二");
		map2.put("charge2", "測承辦二");
		map2.put("chief2", "科長二");
		Map<String,String> map3 = new HashMap<>();
		map3.put("n1", "1");
		map3.put("cause", "測試用的案由102年1月32日ABCDEFG。");
		map3.put("committees", "一委員二三");
		map3.put("unit1", "測試單位");
		map3.put("charge1", "測試承辦");
		map3.put("chief1", "科長一");
		Map<String,String> map4 = new HashMap<>();
		map4.put("n1", "1");
		map4.put("cause", "測試用的案由102年1月32日ABCDEFG。");
		map4.put("committees", "一委員二三");
		map4.put("unit1", "測試單位");
		map4.put("charge1", "測試承辦");
		map4.put("chief1", "科長一");
		replaceAndCloneTr(tempTable,Arrays.asList(map2,map3,map4),template);
		List<Object> ps = getAllElementFromObject(tempTable, P.class);
		for(Object obj :ps){
			P temp = (P)obj;
			List<Object> txts = getAllElementFromObject(temp, Text.class);
			for(Object obj2 :txts){
				Text txt = (Text)obj2;
				
				System.out.println("value"+txt.getValue());
				
			}
		}
		System.out.println("ps:"+ps.size());
		P tempP = getTemplateP(ps, "committees");
		System.out.println(tempP==null?"null":"not null");
		List<Object> rss = getAllElementFromObject(tempTable, R.class);
		R testR = getTemplateR(rss, "committees");
		R newR = XmlUtils.deepCopy(testR);
		int pos5 = tempTable.getContent().indexOf(testR);
		int pos4 = tempP.getContent().indexOf(testR);
		int pos1 = tempTable.getContent().indexOf(tempP);
		int pos = template.getMainDocumentPart().getContent().indexOf(tempP);
		System.out.println("!!!!"+pos5+"%%%%"+pos4+"####"+pos1+"where:"+pos);
		Map<String, String> tempMap = new HashMap<>();
//		tempMap.put("committees", "");
		P newP = cloneP(tempP, tempMap);
		ObjectFactory objFactory = Context.getWmlObjectFactory();
		int count = 0;
		for (String committee : Arrays.asList("一委員三三二三","一委員二三","一委員二三")) {
			count++;
			Text txt = objFactory.createText();
			txt.setValue(committee);
			newR.getContent().add(txt);
			if (count != 3) {
				Br br = objFactory.createBr();
				newR.getContent().add(br);
			}
			
		}
		tempP.getContent().set(pos4, newR);
		
		
		
		MailMerger.performMerge(template, map, true);
//		WordprocessingMLPackage output = MailMerger.getConsolidatedResultCrude(template, Arrays.asList(map2,map7), true);
		template.save(new java.io.File("D:\\REPORT_3.docx"));
		System.out.println("end");
	}
	
	
	private static void replaceAndCloneTr(Tbl tempTable, List<Map<String, String>> textToAdd,
			WordprocessingMLPackage template) throws Docx4JException, JAXBException {
		// 1. find the table
			List<Object> rows = getAllElementFromObject(tempTable, Tr.class);
			Tr templateRow = (Tr) rows.get(0);
			for (int i = 0; i<textToAdd.size();i++) {
				Map<String, String> replacements = textToAdd.get(i);
				Tr workingrow = (Tr) XmlUtils.deepCopy(templateRow);
				List<?> textElements = getAllElementFromObject(workingrow, Text.class);
				System.out.println("textElements size:"+textElements.size());
				for (int j= 0; j<textElements.size();j++) {
					Object obj = textElements.get(j);
					Text text = (Text) obj;
					System.out.println("textValue:"+text.getValue());
					String replacementValue = (String) replacements.get(text.getValue());
					if (replacementValue != null){
						System.out.println("replacement:"+replacementValue);
						text.setValue(replacementValue);
					}else if(StringUtils.indexOfAny(text.getValue(), new String[]{"sep","unit2","charge2","chief2"})>-1){
						System.out.println("remove@@@@@@@@@@@@@@@@@");
						System.out.println(workingrow.getContent().remove(obj));
					}
				}
				tempTable.getContent().add(workingrow);
			}
//			 4. remove the template row
			tempTable.getContent().remove(templateRow);
			System.out.println("replace end");
	}
	
	
	private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {
		
		List<Object> result = new ArrayList<Object>();
		if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();
 
		if (obj.getClass().equals(toSearch))
			result.add(obj);
		else if (obj instanceof ContentAccessor) {
			List<?> children = ((ContentAccessor) obj).getContent();
			for (Object child : children) {
				result.addAll(getAllElementFromObject(child, toSearch));
			}
 
		}
		return result;
	}
	
	private static Tbl getTemplateTable(List<Object> tables, String templateKey) throws Docx4JException, JAXBException {
		System.out.println("table size:"+tables.size());
		for (Iterator<Object> iterator = tables.iterator(); iterator.hasNext();) {
			Object tbl = iterator.next();
			List<?> textElements = getAllElementFromObject(tbl, Text.class);
			for (Object text : textElements) {
				Text textElement = (Text) text;
				System.out.println("col value:"+textElement.getValue());
				if(StringUtils.equals(textElement.getValue(), templateKey))
					return (Tbl) tbl;
			}
		}
		return null;
	}
	
	private static Tbl cloneTable(Tbl reviewtable,  Map<String, String> replacements) {
		System.out.println("begin clone");
		Tbl workingTable = (Tbl) XmlUtils.deepCopy(reviewtable);
		List<Object> rows = getAllElementFromObject(workingTable, Tr.class);
		Tr templateRow = (Tr) rows.get(1);
		List<?> textElements = getAllElementFromObject(templateRow, Text.class);
		System.out.println("textElements size:"+textElements.size());
		for (Object object : textElements) {
			Text text = (Text) object;
			System.out.println("textValue:"+text.getValue());
			String replacementValue = (String) replacements.get(text.getValue());
			if (replacementValue != null){
				System.out.println("replacement:"+replacementValue);
				text.setValue(replacementValue);
			}
		}
		return workingTable;
	}
	
	private static P getTemplateP(List<Object> ps, String templateKey) throws Docx4JException, JAXBException {
		for (Iterator<Object> iterator = ps.iterator(); iterator.hasNext();) {
			Object p = iterator.next();
			List<?> textElements = getAllElementFromObject(p, Text.class);
			 System.out.println("getTemplateP textsize:" +
			 textElements.size());
			for (Object text : textElements) {
				Text textElement = (Text) text;
				 System.out.println("getTemplateP textvalue:" +
				 textElement.getValue());
				if (StringUtils.equals(textElement.getValue(), templateKey))
					return (P) p;
			}
		}
		return null;
	}
	
	private static R getTemplateR(List<Object> ps, String templateKey) throws Docx4JException, JAXBException {
		for (Iterator<Object> iterator = ps.iterator(); iterator.hasNext();) {
			Object p = iterator.next();
			List<?> textElements = getAllElementFromObject(p, Text.class);
			 System.out.println("getTemplateR textsize:" +
			 textElements.size());
			for (Object text : textElements) {
				Text textElement = (Text) text;
				 System.out.println("getTemplateR textvalue:" +
				 textElement.getValue());
				if (StringUtils.equals(textElement.getValue(), templateKey))
					return (R) p;
			}
		}
		return null;
	}
	
	private static P cloneP(P p, Map<String, String> replacements) {
		P tempP = (P) XmlUtils.deepCopy(p);
		List<?> textElements = getAllElementFromObject(tempP, Text.class);
		for (Object object : textElements) {
			Text text = (Text) object;
			String replacementValue = (String) replacements.get(text.getValue());
			if (replacementValue != null) {
				text.setValue(replacementValue);
			}
		}
		return tempP;
	}

}
